package cn.iwgang.simplifyspan;

import cn.iwgang.simplifyspan.other.*;
import cn.iwgang.simplifyspan.unit.BaseSpecialUnit;
import cn.iwgang.simplifyspan.unit.SpecialTextUnit;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.text.Font;
import ohos.agp.text.RichText;
import ohos.agp.text.RichTextBuilder;
import ohos.agp.text.TextForm;
import ohos.agp.utils.TextTool;
import ohos.multimodalinput.event.TouchEvent;

import java.util.ArrayList;
import java.util.List;

/**
 * 辅助类
 *
 * @author wl
 * @since 2021-06-24
 */
public class SimplifySpanBuild {
    private RichTextBuilder richTextBuilder;
    private String[] splitStr = new String[]{};
    private String initializeNormalText = "";
    private ArrayList<BaseSpecialUnit> baseSpecialUnits;
    /**
     * 点击事件的集合
     */
    private ArrayList<OnClickableSpanListener> clickLisenterList;
    /**
     * 点击区域字符串的集合
     */
    private ArrayList<PositionInfo> clickStr;
    private Text textView;

    /**
     * SimplifySpanBuild
     *
     * @param textView           Text
     * @param normalSpecialUnits List<BaseSpecialUnit>
     */
    public SimplifySpanBuild(Text textView, List<BaseSpecialUnit> normalSpecialUnits) {
        this.textView = textView;
        init(normalSpecialUnits);
    }

    private void init(List<BaseSpecialUnit> normalSpecialUnits) {
        richTextBuilder = new RichTextBuilder();
        baseSpecialUnits = new ArrayList<>();
        clickLisenterList = new ArrayList<>();
        this.clickStr = new ArrayList<>();
        for (int i = 0; i < normalSpecialUnits.size(); i++) {
            baseSpecialUnits.add(normalSpecialUnits.get(i));
            initializeNormalText += normalSpecialUnits.get(i).getStartText();
            ArrayList<OnClickableSpanListener> clickLisenter = normalSpecialUnits.get(i).getClickLisenter();
            ArrayList<String> list = normalSpecialUnits.get(i).getClickStr();
            if (clickLisenter != null && clickLisenter.size() > 0) {
                for (int j = 0; j < clickLisenter.size(); j++) {
                    clickLisenterList.add(normalSpecialUnits.get(i).getClickLisenter().get(j));
                }
            }
            if (list != null && list.size() > 0) {
                for (int k = 0; k < list.size(); k++) {
                    int startClickIndex = 0;
                    if (normalSpecialUnits.get(i) instanceof SpecialTextUnit) {
                        SpecialTextUnit specialUnit = (SpecialTextUnit) normalSpecialUnits.get(i);
                        switch (((SpecialTextUnit) specialUnit).getConvertMode()) {
                            case SpecialConvertMode.ONLY_FIRST:
                                startClickIndex = getInitializeNormalText().indexOf(list.get(k));
                                break;
                            case SpecialConvertMode.ONLY_LAST:
                                startClickIndex = getInitializeNormalText().lastIndexOf(list.get(k));
                                break;
                            default:
                                startClickIndex = getInitializeNormalText().indexOf(list.get(k));
                                break;
                        }
                    }
                    int endClickIndex = startClickIndex + list.get(k).length();
                    int textLenght = startClickIndex + list.get(k).length();
                    String data = list.get(k);
                    PositionInfo positionInfo = new PositionInfo(startClickIndex, endClickIndex, textLenght, data);
                    this.clickStr.add(positionInfo);
                }
            }
        }
    }

    /**
     * append
     *
     * @param specialUnit
     * @return SimplifySpanBuild
     */
    public SimplifySpanBuild append(BaseSpecialUnit specialUnit) {
        initializeNormalText += specialUnit.getStartText();
        baseSpecialUnits.add(specialUnit);
        ArrayList<OnClickableSpanListener> clickLisenter = specialUnit.getClickLisenter();
        ArrayList<String> clickStrList = specialUnit.getClickStr();
        if (clickLisenter != null && clickLisenter.size() > 0) {
            for (int j = 0; j < clickLisenter.size(); j++) {
                clickLisenterList.add(clickLisenter.get(j));
            }
        }
        if (clickStrList != null && clickStrList.size() > 0) {
            for (int k = 0; k < clickStrList.size(); k++) {
                int startClickIndex = 0;
                if (specialUnit instanceof SpecialTextUnit) {
                    switch (((SpecialTextUnit) specialUnit).getConvertMode()) {
                        case SpecialConvertMode.ONLY_FIRST:
                            startClickIndex = getInitializeNormalText().indexOf(clickStrList.get(k));
                            break;
                        case SpecialConvertMode.ONLY_LAST:
                            startClickIndex = getInitializeNormalText().lastIndexOf(clickStrList.get(k));
                            break;
                        default:
                            startClickIndex = getInitializeNormalText().indexOf(clickStrList.get(k));
                            break;
                    }
                }
                int endClickIndex = startClickIndex + clickStrList.get(k).length();
                int textLenght = startClickIndex + clickStrList.get(k).length();
                String data = clickStrList.get(k);
                PositionInfo positionInfo = new PositionInfo(startClickIndex, endClickIndex, textLenght, data);
                this.clickStr.add(positionInfo);
            }
        }
        return this;
    }

    /**
     * 构建字体风格
     *
     * @return RichText
     */
    public RichText build() {
        if (!StrUtil.isListEmpty(baseSpecialUnits)) {
            for (int k = 0; k < baseSpecialUnits.size(); k++) {
                BaseSpecialUnit temUnit = baseSpecialUnits.get(k);
                if (temUnit != null) {
                    splitStr = temUnit.getStartText().split(temUnit.getText());
                    handleSpecialUnit(temUnit);
                }
            }
        }
        RichText richText = richTextBuilder.build();
        if (!StrUtil.isListEmpty(clickLisenterList)) {
            for (int i = 0; i < clickLisenterList.size(); i++) {
                int startClickIndex = clickStr.get(i).startPos;
                int endClickIndex = clickStr.get(i).endPos;
                String data = (String) clickStr.get(i).data;
                int index = i;
                richText.addTouchEventListener(new RichText.TouchEventListener() {
                    @Override
                    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                        if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP) {
                            if (clickLisenterList.get(index) != null) {
                                clickLisenterList.get(index).onClick(data);
                            }
                        }
                        return true;
                    }
                }, startClickIndex, endClickIndex);
            }
        }
        return richText;
    }

    private void handleSpecialUnit(BaseSpecialUnit temUnit) {
        if (temUnit != null && !TextTool.isNullOrEmpty(temUnit.getStartText())) {
            if (temUnit instanceof SpecialTextUnit) {
                if (splitStr != null && splitStr.length > 0) {
                    handleSplitStr((SpecialTextUnit) temUnit);
                } else {
                    SpecialTextUnit specialTextUnit = (SpecialTextUnit) temUnit;
                    TextForm textForm = new TextForm();
                    setStyle((SpecialTextUnit) temUnit, textForm);
                    setTextForm(textForm, specialTextUnit.getText());
                }
            }
        }
    }

    private void handleSplitStr(SpecialTextUnit temUnit) {
        for (int i = 0; i < splitStr.length; i++) {
            SpecialTextUnit specialTextUnit = temUnit;
            TextForm textFormStart = new TextForm().setTextSize(textView.getTextSize()).setTextColor(textView.getTextColor().getValue());
            setTextForm(textFormStart, splitStr[i]);
            TextForm textForm = new TextForm();
            int count = StrUtil.checkStrEndFoundCount(specialTextUnit.getStartText(), specialTextUnit.getText());
            if (specialTextUnit.getConvertMode() == SpecialConvertMode.ONLY_FIRST) {
                if (i == 0) {
                    setStyle(specialTextUnit, textForm);
                } else {
                    textForm = textFormStart;
                }
            } else if (specialTextUnit.getConvertMode() == SpecialConvertMode.ONLY_LAST) {
                textForm = textFormStart;
            } else {
                setStyle(specialTextUnit, textForm);
            }
            if (i == splitStr.length - 1) {
                handleCountUP0(specialTextUnit, textFormStart, textForm, count);
            } else if (splitStr.length >= 2 && i == splitStr.length - 2 && count <= 0) {
                setStyle(specialTextUnit, textForm);
                setTextForm(textForm, specialTextUnit.getText());
            } else {
                setTextForm(textForm, specialTextUnit.getText());
            }
        }
    }

    private void handleCountUP0(SpecialTextUnit specialTextUnit, TextForm textFormStart, TextForm textForm, int count) {
        if (count > 0) {
            for (int j = 0; j < count; j++) {
                if (specialTextUnit.getConvertMode() == SpecialConvertMode.ONLY_LAST) {
                    if (j == count - 1) {
                        setStyle(specialTextUnit, textForm);
                        setTextForm(textForm, specialTextUnit.getText());
                    } else {
                        setTextForm(textFormStart, specialTextUnit.getText());
                    }
                }

            }
        }
    }

    /**
     * 设置字体风格
     *
     * @param textForm TextForm
     * @param text String
     */
    private void setTextForm(TextForm textForm, String text) {
        richTextBuilder.mergeForm(textForm);
        richTextBuilder.addText(text);
        richTextBuilder.revertForm();
    }

    private void setStyle(SpecialTextUnit specialTextUnit, TextForm textForm) {
        if (specialTextUnit.getTextColor() != 0) {
            textForm.setTextColor(specialTextUnit.getTextColor());
        } else {
            textForm.setTextColor(textView.getTextColor().getValue());
        }
        if (specialTextUnit.getTextSize() != 0) {
            textForm.setTextSize(specialTextUnit.getTextSize());
        } else {
            textForm.setTextSize(textView.getTextSize());
        }
        if (specialTextUnit.isShowUnderline()) {
            textForm.setUnderline(specialTextUnit.isShowUnderline());
        }
        if (specialTextUnit.isShowStrikeThrough()) {
            textForm.setStrikethrough(specialTextUnit.isShowStrikeThrough());
        }
        if (specialTextUnit.isTextBold()) {
            specialTextUnit.setFont(Font.DEFAULT_BOLD);
        } else {
            textForm.setTextFont(textView.getFont());
        }
        if (specialTextUnit.isTextItalic()) {
            Font font = new Font.Builder("myfont").makeItalic(true).build();
            specialTextUnit.setFont(font);
        } else {
            textForm.setTextFont(textView.getFont());
        }
        if (specialTextUnit.getTextBackgroundColor() != 0) {
            textForm.setTextBackgroundColor(specialTextUnit.getTextBackgroundColor());
        } else {
        }
        setFont(specialTextUnit, textForm);
        setGravity(specialTextUnit, textForm);
    }

    private void setGravity(SpecialTextUnit specialTextUnit, TextForm textForm) {
        if (specialTextUnit.getGravity() != 0) {
            if (specialTextUnit.getGravity() == SpecialGravity.TOP) {
                textForm.setSuperscript(true);
            } else if (specialTextUnit.getGravity() == SpecialGravity.BOTTOM) {
                textForm.setSubscript(true);
            } else if (specialTextUnit.getGravity() == SpecialGravity.CENTER) {
                textForm.setSubscript(true);
            }else {}
        }
    }

    private void setFont(SpecialTextUnit specialTextUnit, TextForm textForm) {
        if (specialTextUnit.getFont() != null) {
            textForm.setTextFont(specialTextUnit.getFont());
        } else {
            textForm.setTextFont(textView.getFont());
        }
    }

    /**
     * 返回拼接完后的总字符串
     *
     * @return String
     */
    public String getInitializeNormalText() {
        return initializeNormalText;
    }

    static class PositionInfo {
        int startPos;
        int textLength;
        int endPos;
        Object data;

        PositionInfo(int startPos, int endPos, int textLength, Object data) {
            this.startPos = startPos;
            this.endPos = endPos;
            this.textLength = textLength;
            this.data = data;
        }

        @Override
        public String toString() {
            return "PositionInfo{" +
                    "startPos=" + startPos +
                    ", textLength=" + textLength +
                    ", endPos=" + endPos +
                    ", data=" + data +
                    '}';
        }
    }
}
